#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "mqtt_client.h"
#include "string.h"
#include "app_wifi.h"
#include "esp_log.h"
#include "app_smartconfig.h"

#define MAX_RETRY 5
static int retry_num = 0;
bool wifi_is_connected = false;
static const char *TAG = "wifi_sta";

void esp_event_wifi_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
    // Station模式，设备作为客户端连接到一个 WiFi 路由器。
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
    {
        ESP_LOGI(TAG, "wifi sta start!\n");
        esp_wifi_connect();
    }

    // 连接到WiFi
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED)
    {
        ESP_LOGI(TAG, "wifi connected!\n");
        wifi_is_connected = true;
        retry_num = 0;
    }

    // 错误，开始配网，重连
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        ESP_LOGE(TAG, "wifi disconnected!\n");
        wifi_is_connected = false;
        wifi_event_sta_disconnected_t *disconnected = (wifi_event_sta_disconnected_t *)event_data;
        // 账号密码错误
        if (disconnected->reason == WIFI_REASON_AUTH_FAIL || disconnected->reason == WIFI_REASON_ASSOC_FAIL)
        {
            ESP_LOGE(TAG, " Wrong SSID or password.\n");
            app_smartconfig_start();
        }
        else if (disconnected->reason == WIFI_REASON_AUTH_LEAVE)
        {
            ESP_LOGE(TAG, "User disconnected from WiFi network.\n");
            esp_wifi_disconnect();
        }
        else
        {
            if (retry_num < MAX_RETRY) // 五次内重新连接
            {
                esp_wifi_connect();
                retry_num++;
                ESP_LOGI(TAG, "attempting to connect…………\n");
            }
        }
    }

    // IP
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    {
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        ESP_LOGI(TAG, "Got IP: " IPSTR "\n", IP2STR(&event->ip_info.ip));
        wifi_is_connected = true;
    }
}

void app_wifi_init()
{
    esp_netif_init();
    esp_netif_create_default_wifi_sta();
    esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, esp_event_wifi_handler, NULL);
    esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, esp_event_wifi_handler, NULL);
    wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT();

    esp_wifi_init(&wifi_cfg);

    esp_wifi_set_mode(WIFI_MODE_STA);

    // 启动wifi连接
    esp_wifi_start();
}

// 连接wifi
void app_wifi_connect(char *ssid, char *password)
{

    if (ssid == NULL || password == NULL)
    {
        ESP_LOGE(TAG, "SSID or Password is NULL");
        return;
    }
    wifi_config_t cfg = {
        .sta.ssid = "",
        .sta.password = "",
        .sta.threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK,
    };
    //将字符串ssid和password使用 strlcpy赋值到cfg中
    memset(&cfg, 0, sizeof(wifi_config_t));
    strlcpy((char *)cfg.sta.ssid, ssid, sizeof(cfg.sta.ssid));
    strlcpy((char *)cfg.sta.password, password, sizeof(cfg.sta.password));

    if (wifi_is_connected)
    {
        ESP_LOGI(TAG, "disconneted wifi!!!\n");
        esp_wifi_disconnect();
    }
    else
    {
        esp_wifi_set_config(ESP_IF_WIFI_STA, &cfg);
        esp_wifi_connect();
    }
}